// worker.js
const { parentPort } = require("worker_threads");
const path = require("path");
const fs = require("fs");
const ffi = require("@breush/ffi-napi");
const ref = require("@breush/ref-napi");
const iconv = require("iconv-lite");
const { getHctpLib } = require("./hctpLib.js");
const libDllPath = path.join(__dirname, "../../sdk/x64/libHCTP.dll");
const dllerror = require("./dllerror.js");
const { getDownloadName, setRenameDownloadFile } = require("./rename.js");

// 从主线程接收消息
parentPort.on("message", (message) => {
  // console.log("worker message", message);

  // #region 同步任务
  if (message.type === "DownloadMediaStart") {
    handleDownloadMedia(message);
  }
  if (message.type === "UploadMediaStart") {
    handleUploadMedia(message);
  }
  // #endregion 同步任务
  parentPort.close();
});

function handleUploadMedia(message) {
  // console.log("handleUploadMedia message", message);
  const hctpInstance = getHctpLib(libDllPath);

  const md5Str = hctpWrapperGetFileMd5(hctpInstance, message.filePath);

  // console.log("handleUploadMedia md5Str", md5Str);

  const newItem = {
    id: message.taskid,
    uidStr: message.userid,
    md5Str: md5Str,
    szLocalFilename: iconv.encode(message.filePath, "gbk"),
    szRemoteFilename: path.basename(message.filePath),
    szJsonString: JSON.stringify({
      version: message.playload.version,
      fsize: message.fileSize,
      ctime: message.playload.ctime,
      mtime: message.playload.mtime,
      shootingtime: message.playload.shootTime,
      owner: message.fileOwner,
      ftype: message.fileType,
      md5: md5Str, // 不是标准的md5
      showname: message.fileName,
      token: message.token,
      albumid: message.playload.albumid,
      md5: md5Str,
    }),
    callback: ffi.Callback("void", ["int"], (progress) => {
      // console.log("progress", progress);
      message.port.postMessage({
        taskid: message.taskid,
        type: "progress",
        uuid: message.uuid,
        progress,
        msg: "进行中",
      });
    }),
  };
  const result = hctpInstance.hctpNewUploadMedia(
    message.hctpHandle,
    newItem.id,
    newItem.uidStr,
    newItem.md5Str,
    newItem.szLocalFilename,
    newItem.szRemoteFilename,
    newItem.szJsonString,
    newItem.callback
  );

  message.port.postMessage({
    taskid: message.taskid,
    type: "ended",
    code: result,
    uuid: message.uuid,
    msg: dllerror.getMapHctpRetText(result),
  });
}

function handleDownloadMedia(message) {
  const hctpInstance = getHctpLib(libDllPath);

  const myGbkPath = path.join(
    __dirname,
    "../../img/",
    getDownloadName(message.taskid)
  );
  const targetDirectory = path.dirname(myGbkPath);

  // 检查目录是否已经存在
  if (!fs.existsSync(targetDirectory)) {
    // 如果目录不存在，则创建它
    fs.mkdirSync(targetDirectory, { recursive: true });
  }

  const newItem = {
    id: message.taskid,
    uidStr: message.userid,
    md5Str: message.playload.md5,
    szLocalFilename: iconv.encode(myGbkPath, "gbk"),
    szJsonString: JSON.stringify({
      owner: message.fileOwner,
      devicetype: "Windows",
      token: message.token,
      albumid: message.playload.albumid,
    }),
    callback: ffi.Callback("void", ["int"], (progress) => {
      // console.log("progress", progress);
      message.port.postMessage({
        taskid: message.taskid,
        type: "progress",
        uuid: message.uuid,
        progress,
        msg: "进行中",
      });
    }),
    retjson: Buffer.alloc(1024 * 10),
    jsonSize: 1024 * 10,
  };

  const result = hctpInstance.hctpNewDownloadMedia(
    message.hctpHandle,
    newItem.id,
    newItem.uidStr,
    newItem.md5Str,
    newItem.szLocalFilename,
    newItem.szJsonString,
    newItem.callback,
    newItem.retjson,
    newItem.jsonSize
  );
  let jsonObject;
  if (result === 0) {
    try {
      const jsonString = newItem.retjson.toString("utf8").split("\u0000")[0]; // Remove any null bytes
      jsonObject = JSON.parse(jsonString);
      const filename = jsonObject.filename[jsonObject.filename.length - 1];
      filename &&
        setRenameDownloadFile({
          downloadDirectory: targetDirectory,
          taskid: message.taskid,
          name: filename,
        });
    } catch (error) {
      console.error("jsonObject error", error);
    }
  }

  message.port.postMessage({
    jsonObject,
    taskid: message.taskid,
    type: "ended",
    code: result,
    uuid: message.uuid,
    msg: dllerror.getMapHctpRetText(result),
  });
}

function hctpWrapperGetFileMd5(hctpInstance, filePath) {
  try {
    const filemd5Str = Buffer.alloc(64);
    const myGbkPath = iconv.encode(filePath, "gbk");

    const decodedText = iconv.decode(myGbkPath, "gbk");
    if (filePath !== decodedText) {
      throw new Error("文件名含全角字符");
    }
    const result = hctpInstance.hctpGetFileMd5(myGbkPath, filemd5Str);
    if (!fs.existsSync(path.resolve(filePath))) {
      console.error("Error: File does not exist");
    }

    if (result !== -1) {
      const md5EndIndex = filemd5Str.indexOf("\x00");
      const md5 = filemd5Str.toString("utf8", 0, md5EndIndex);
      return md5;
    } else {
      throw new Error("Error getting file MD5");
    }
  } catch (error) {
    throw error;
  }
}
